package org.hentor.modules.generate.generate.fileGenrate;

import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.hentor.common.exception.HentorAdminException;
import org.hentor.modules.generate.dto.GenerateFileDTO;
import org.hentor.modules.generate.utils.CamelCaseUtil;
import org.hentor.generate.entity.GenerateDevDetail;
import org.hentor.generate.entity.GenerateDevMain;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.*;

/**
 * 后端代码生成
 */
@Slf4j
public class VueFileGenerate extends AbstractFileGenerate{

    @Override
    public List<String> generate(GenerateFileDTO generateFileDTO) {
        //固定路径
        String tempPath = "hentor-generate.hentor-generate-service.src.main.resources.temp.vue.";
        ArrayList<String> pathList = new ArrayList<>();
        //api文件
        pathList.add(generateApi(generateFileDTO,tempPath));
        //data文件生成
        pathList.add(generateData(generateFileDTO,tempPath));
        //modal文件生成
        pathList.add(generateModal(generateFileDTO,tempPath));
        //index文件生成
        pathList.add(generateIndex(generateFileDTO,tempPath));
        return pathList;
    }


    /**
     * modal文件生成
     * @return
     */
    private String generateIndex(GenerateFileDTO generateFileDTO,String tempPath){
        GenerateDevMain generateDevMain = generateFileDTO.getGenerateDevMain();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //自定义包名
        String packagePath = generateFileDTO.getPackagePath();

        //全路径
        String path = (tempPath+packagePath).replace(".", "/");;
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/vue/Index.vm");
        VelocityContext context = new VelocityContext();
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(generateDevMain.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorAdminException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/index.vue";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:index文件生成成功，路径%s",filePath));
        return filePath;
    }



    /**
     * modal文件生成
     * @return
     */
    private String generateModal(GenerateFileDTO generateFileDTO,String tempPath){
        GenerateDevMain generateDevMain = generateFileDTO.getGenerateDevMain();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //自定义包名
        String packagePath = generateFileDTO.getPackagePath();

        //全路径
        String path = (tempPath+packagePath).replace(".", "/");;
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/vue/Modal.vm");
        VelocityContext context = new VelocityContext();
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(generateDevMain.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorAdminException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/"+CamelCaseUtil.underscoreToCamelCase(generateDevMain.getTableName(),true)+"Modal.vue";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:modal文件生成成功，路径%s",filePath));
        return filePath;
    }


    /**
     * data文件生成
     * @return
     */
    private String generateData(GenerateFileDTO generateFileDTO,String tempPath){
        GenerateDevMain generateDevMain = generateFileDTO.getGenerateDevMain();
        List<GenerateDevDetail> generateDevDetailList = generateFileDTO.getGenerateDevDetailList();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();

        //自定义包名
        String packagePath = generateFileDTO.getPackagePath();
        //全路径
        String path = (tempPath+packagePath).replace(".", "/");;
        Template template = velocityEngine.getTemplate("templates/vue/Data.vm");
        VelocityContext context = new VelocityContext();
        List<HashMap<String, Object>> fields = new ArrayList<>();
        generateDevDetailList.stream().filter(x->!"id".equals(x.getColumnName())).sorted(Comparator.comparing(GenerateDevDetail::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            fields.add(field);
        });
        context.put("fields", fields);
        List<HashMap<String, Object>> searchFields = new ArrayList<>();
        generateDevDetailList.stream().filter(x->x.getIsQuery() != null && x.getIsQuery() == 1).sorted(Comparator.comparing(GenerateDevDetail::getSortOrder)).forEachOrdered(x->{
            HashMap<String, Object> field = createField(x);
            searchFields.add(field);
        });
        context.put("searchFields", searchFields);
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorAdminException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/"+CamelCaseUtil.underscoreToCamelCase(generateDevMain.getTableName(),false)+".data.ts";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:data文件生成成功，路径%s",filePath));
        return filePath;
    }



    /**
     * api文件生成
     * @return
     */
    private String generateApi(GenerateFileDTO generateFileDTO,String tempPath){
        GenerateDevMain generateDevMain = generateFileDTO.getGenerateDevMain();
        VelocityEngine velocityEngine = generateFileDTO.getVelocityEngin();
        //自定义包名
        String packagePath = generateFileDTO.getPackagePath();

        //全路径
        String path = (tempPath+packagePath).replace(".", "/");;
        //entity文件名
        Template template = velocityEngine.getTemplate("templates/vue/Api.vm");
        VelocityContext context = new VelocityContext();
        context.put("entityNameLower", CamelCaseUtil.underscoreToCamelCase(generateDevMain.getTableName(),false));
        File  directory = new File(path);
        if (!directory.exists()) {
            boolean mkdirs = directory.mkdirs();
            if(!mkdirs){
                throw new HentorAdminException(path+"目录创建失败！");
            }
        }
        String filePath = path+"/"+CamelCaseUtil.underscoreToCamelCase(generateDevMain.getTableName(),false)+".api.ts";
        try (Writer writer = new FileWriter(filePath)) {
            template.merge(context, writer);
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        log.info(String.format("vue:api文件生成成功，路径%s",filePath));
        return filePath;
    }


    private static List<String> generateImports(List<String> types) {
        List<String> imports = new ArrayList<>();
        for (String type : types) {
            if ("Date".equals(type)) {
                imports.add("java.util.Date");
            }else if("BigDecimal".equals(type)){
                imports.add("import java.math.BigDecimal");
            }
        }
        return imports;
    }

    private static HashMap<String, Object> createField(GenerateDevDetail generateDevDetail) {
        HashMap<String, Object> field = new HashMap<>(7);
        field.put("formModule", generateDevDetail.getFormModule());
        field.put("searchModule", generateDevDetail.getSearchModule());
        field.put("isRequired", generateDevDetail.getIsRequired() != null && generateDevDetail.getIsRequired() == 1);
        field.put("name", CamelCaseUtil.underscoreToCamelCase(generateDevDetail.getColumnName(), false));
        field.put("description", generateDevDetail.getColumnDesc());
        field.put("columnWidth", generateDevDetail.getColumnWidth());
        field.put("searchSpan", generateDevDetail.getSearchSpan());
        return field;
    }
}
